#pragma once

#include "MasterList.hpp"
#include <iostream>
#include <cstdlib>

typedef int ElemType;

typedef struct {
    ElemType* elem;
    int length;
} SqList;

class SqListC : public MasterList<SqList, ElemType> {
public:
    Status initList(SqList& l) override
    {
        l.elem = new ElemType[ListMaxSize];
        if (!l.elem)
            exit(0);
        l.length = 0;
        return Status::Ok;
    }

    Status destoryList(SqList& l) override
    {
        delete[] l.elem;
        l.elem = nullptr;
        l.length = 0;
        return Status::Ok;
    }

    Status clearList(SqList& l) override
    {
        delete[] l.elem;
        l.elem = new ElemType[ListMaxSize];
        l.length = 0;
        return Status::Ok;
    }

    inline bool listEmpty(const SqList l) override
    {
        return l.length == 0;
    }

    inline int listLength(const SqList l) override
    {
        return l.length;
    }

    Status getElem(const SqList l, int i, ElemType& e) override
    {
        if (!l.elem || l.length < i || i < 0)
            return Status::Err;
        e = l.elem[i];
        return Status::Ok;
    }

    int locateElem(const SqList l, const ElemType e) override
    {
        if (!l.elem)
            return -1;
        for (int i = 0; i < l.length; i++) {
            if (l.elem[i] == e)
                return i;
        }
        return -1;
    }

    Status priorElem(const SqList l, const ElemType cur_e, ElemType& pre_e) override
    {
        if (!l.elem)
            return Status::Err;
        for (int i = 0; i < l.length - 1; i++) {
            if (l.elem[i + 1] == cur_e) {
                pre_e = l.elem[i];
                return Status::Ok;
            }
        }
        return Status::Err;
    }

    Status nextElem(const SqList l, const ElemType cur_e, ElemType& next_e) override
    {
        if (!l.elem)
            return Status::Err;
        for (int i = 0; i < l.length - 1; i++) {
            if (l.elem[i] == cur_e) {
                next_e = l.elem[i + 1];
                return Status::Ok;
            }
        }
        return Status::Err;
    }

    Status listInsert(SqList& l, int i, ElemType e) override
    {
        if (!l.elem || l.length < i || i < 0)
            return Status::Err;
        for (int j = l.length; j > i; j++) {
            l.elem[j - 1] = l.elem[j];
        }
        l.elem[i] = e;
        l.length++;
        return Status::Ok;
    }

    Status listDelete(SqList& l, int i) override
    {
        if (!l.elem || l.length < i || i < 0)
            return Status::Err;
        for (int j = i; j < l.length - 1; j++) {
            l.elem[j] = l.elem[j + 1];
        }
        l.length--;
        return Status::Ok;
    }

    Status traverseList(const SqList l) override
    {
        if (!l.elem)
            return Status::Err;
        for (int i = 0; i < l.length; i++) {
            std::cout << l.elem[i] << std::endl;
        }
        return Status::Ok;
    }
};
